package com.yyq.sos.service;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.metadata.ClassMetadata;
import org.springframework.transaction.annotation.Transactional;

import com.yyq.adms.usermanage.pojo.SysDepts;
import com.yyq.adms.usermanage.pojo.SysUsers;
import com.yyq.sos.dao.BaseDao;
import com.yyq.sos.permission.LoginUser;
import com.yyq.sos.util.ObjectUtil;
import com.yyq.sos.util.page.PageFormData;

@Transactional
public class BaseBpoImpl implements BaseBpo
{
	protected static final Log log = LogFactory.getLog(BaseBpoImpl.class);
	private Session session;
	private BaseDao dao;
	private Class cls;
	
	public void beginTransaction(){
		session.beginTransaction();
	}

	public void commitTransaction(){

	}

	public void setBaseDao(BaseDao _dao){
		this.dao = _dao;
	}

	public BaseBpoImpl(){};

	/**
	 * 构造函数
	 * @param _dao
	 * @param _cls
	 */
	public BaseBpoImpl(BaseDao _dao)
	{
		this.dao = _dao;
	}

	public List searchSql(String sql) {
		return dao.listSql(sql);
	}

//	public PageFormData searchSqlPage(String sql, int page, int size) {
//		List cnt = dao.listSql("select count(*) from ("+sql+") tt");
//		long count = Long.valueOf(cnt.get(0)+"").longValue();
//		if((page-1)*size>count)
//			page =1;
//		List list = dao.listSql(sql, page, size);
//		return new PageFormData(list,count,page,size);
//	}

	/**
	 * 有排序字段时处理一下：去掉排序字符串后再查询count(*)
	 */
	public PageFormData searchSqlPage(String sql, int page, int size) {
		int index =  sql.toLowerCase().indexOf(" order by ");
		String str = sql;
		if(index > 0)
			str = sql.substring(0,index);
		List cnt = dao.listSql("select count(*) from ("+str+") tt");
		long count = Long.valueOf(cnt.get(0)+"").longValue();
		if((page-1)*size>count)
			page =1;
		List list = dao.listSql(sql, page, size);
		return new PageFormData(list,count,page,size);
	}

	/**
	 * 构造函数
	 * @param _dao
	 * @param _cls
	 */
	public BaseBpoImpl(BaseDao _dao,Class _cls)
	{
		this.dao = _dao;
		this.cls = _cls;
	}
	public Class getPojoClass()
	{
		return this.cls;
	}
	/**
	 * 查询全部数据
	 */
	public List list()
	{
		return dao.list(cls);
	}

	/**
	 * 查询分页数据，带有分页信息
	 */
	public PageFormData listPage(int page, int size)
	{
		long count = dao.count(cls);
		if((page-1)*size>count)
			page =1;
		List list =  dao.listPage(cls, page, size);
		return new PageFormData(list,count,page,size);
	}

	/**
	 * 查询分页数据，不带有分页信息
	 */
	public List list(int page, int size)
	{
		return dao.listPage(cls, page, size);
	}

	/**
	 * 查询记录数
	 */
	public long count()
	{
		return dao.count(cls);
	}

	/**
	 * 根据sql条件查询记录数
	 */
	public long count(String sql)
	{
		return dao.count(sql);
	}

	/**
	 * 根据主键，删除一条记录
	 */
	public boolean delete(long id)
	{
		return dao.delete(cls, id);
	}

	/**
	 * 根据主键，删除一条记录
	 */
	public boolean delete(Serializable id)
	{
		return dao.delete(cls, id);
	}

	/**
	 * 根据对象，删除一条记录
	 */
	public boolean delete(Object obj)
	{
		return dao.delete(obj);
	}

	/**
	 * 批量删除多条记录
	 */
	public boolean delete(long[] ids)
	{
		return dao.delete(cls, ids);
	}

	/**
	 * 批量删除多条记录
	 */
	public boolean delete(Serializable[] ids)
	{
		return dao.delete(cls, ids);
	}

	/**
	 * 根据sql语句删除记录
	 */
	public boolean delete(String sql)
	{
		return dao.delete(sql);
	}

	/**
	 * 根据主键查找一条记录
	 */
	public Object findByPk(long id)
	{
		return dao.findByPk(cls, id);
	}

	/**
	 * 根据主键查找一条记录
	 */
	public Object findByPk(Serializable id)
	{
		return dao.findByPk(cls, id);
	}

	/**
	 * 保存记录
	 */
	public Serializable save(Object obj)
	{
		processObject(obj);
		return dao.add(obj);
	}
	/**
	 * 处理需要保存的对象，完成默认属性值
	 * @param obj
	 */
	private void processObject(Object obj){

		ObjectUtil.setValue(obj, "setStsTime", new Class[]{Date.class}, new Object[]{new Date()});
		Object value = ObjectUtil.getValue(obj, "getSts", new Class[]{}, new Object[]{});
		if(value == null)
			ObjectUtil.setValue(obj, "setSts", new Class[]{String.class}, new Object[]{"ACTV"});
		ObjectUtil.setValue(obj, "setCreateTime", new Class[]{Date.class}, new Object[]{new Date()});
		ObjectUtil.setValue(obj, "setStsDate", new Class[]{Date.class}, new Object[]{new Date()});
		ObjectUtil.setValue(obj, "setCreateDate", new Class[]{Date.class}, new Object[]{new Date()});

		LoginUser user = (LoginUser)LoginUser.userThread.get();
		if(user != null){
			ObjectUtil.setValue(obj, "setMaintainDep", new Class[]{Long.class}, new Object[]{user.getOrgId()});
			ObjectUtil.setValue(obj, "setOperator", new Class[]{Long.class}, new Object[]{user.getUserId()});
			ObjectUtil.setValue(obj, "setCreator", new Class[]{Long.class}, new Object[]{user.getUserId()});
			Class cls = obj.getClass();
			if(!cls.equals(SysDepts.class) && !cls.equals(SysUsers.class)){
				ObjectUtil.setValue(obj, "setDeptLevel", new Class[]{String.class}, new Object[]{user.getDeptLevel()});
				ObjectUtil.setValue(obj, "setDeptId", new Class[]{Long.class}, new Object[]{user.getUserId()});
				ObjectUtil.setValue(obj, "setDeptId", new Class[]{Integer.class}, new Object[]{new Integer(user.getDeptId().intValue())});
			}
		}
	}
	/**
	 * 更新一个对象实例
	 */
	public boolean update(Object obj)
	{
		ObjectUtil.setValue(obj, "setStsTime", new Class[]{Date.class}, new Object[]{new Date()});
		ObjectUtil.setValue(obj, "setStsDate", new Class[]{Date.class}, new Object[]{new Date()});
		return dao.update(obj);
	}

	/**
	 * 根据sql语句更新一条记录
	 */
	public boolean update(String sql)
	{
		return dao.update(sql);
	}

	/**
	 * 批量保存多条记录
	 */
	public Serializable[] save(Object[] objs)
	{
		if(objs!=null){
			for(int i=0;i<objs.length; ++i){
				processObject(objs[i]);
			}
			return dao.add(objs);
		}else
			return null;
	}

	/**
	 * 批量更新多条记录
	 */
	public boolean update(Object[] objs)
	{
		return dao.update(objs);
	}

	/**
	 * 根据sql查询记录，不带有分页信息
	 */
	public List search(String[] fields,String[] values, int page, int size)
	{
		return dao.search(null, page, size);
	}

	/**
	 * 根据sql查询记录
	 */
	public List search(String sql,String[] values)
	{
		return dao.search(sql);
	}

	/**
	 * 根据sql查询记录，带有分页信息
	 */
	public PageFormData searchPage(String[] fields,String[] values, int page, int size)
	{
		StringBuffer sqlSB = new StringBuffer("from "+this.cls.getName()+" as obj ");
		if(values!=null && fields!=null){
			sqlSB.append(" where ");
			if(values.length==1)
				for(int i=0;i<fields.length; ++i)
					sqlSB.append(" obj."+fields[i]+" like '%"+values[0]+"%'  or");
			else
				for(int i=0;i<fields.length; ++i)
					sqlSB.append(" obj."+fields[i]+" like '%"+values[i]+"%'  or");
		}
		String sql = sqlSB.substring(0, sqlSB.length()-4);
		log.debug("关键字的模糊查询语句："+sql);
		long count = dao.count(sql);
		if((page-1)*size>count)
			page =1;
		List list = dao.search(sql, page, size);
		return new PageFormData(list,count,page,size);
	}

	public List search(String sql, int page, int size)
	{
		return null;
	}

	public List search(String[] fields,String[] values)
	{
		StringBuffer sqlSB = new StringBuffer("from "+this.cls.getName()+" as obj ");
		if(values!=null && fields!=null){
			sqlSB.append(" where ");
			if(values.length==1)
				for(int i=0;i<fields.length; ++i)
					sqlSB.append(" obj."+fields[i]+" = '"+values[0]+"'  or");
			else
				for(int i=0;i<fields.length; ++i)
					sqlSB.append(" obj."+fields[i]+" = '"+values[i]+"'  or");
		}
		String sql = sqlSB.substring(0, sqlSB.length()-4);
		log.debug("关键字的模糊查询语句："+sql);
		List list = dao.search(sql);
		return list;
	}

	public PageFormData searchPage(String sql,int page, int size)
	{


		int idx = sql.toLowerCase().indexOf("from");
		long count = dao.count("select count(*) "+sql.substring(idx));
		if((page-1)*size>count)
			page =1;
		List list = dao.search(sql, page, size);
		return new PageFormData(list,count,page,size);
	}

	public List search(String sql){
		return dao.search(sql);
	}

	public boolean exist(String sql)
	{
		return dao.exist(sql);
	}

	public boolean exist(java.io.Serializable id)
	{
		return dao.exist(cls, id);
	}

	public Object max(String fieldName,String where){
		return dao.max(cls, fieldName, where);
	}

	public boolean execSql(String sql)
	{
		return dao.execSql(sql);
	}

	public boolean validDate(String valueCondition,String effDate,String expDate){
		return dao.validDateAvai(cls, valueCondition,effDate, expDate);
	}
	
	public SessionFactory getSessionFactory(){
		return dao.getSessionFactory();
	}

	public void setCls(Class cls) {
		this.cls = cls;
	}

	public String getTableName(Class cls) {
		return dao.getTableName(cls);
	}

	public boolean logicDelete(Serializable[] ids) {
		return dao.logicDelete(ids);
	}

	public String getOrderByDescStr() {
		ClassMetadata meta = this.getSessionFactory().getClassMetadata(cls);
		String[] fields = meta.getPropertyNames();
		for(int i=0; i<fields.length; ++i){
			if(fields[i].equals("belongYear") 
			  || fields[i].equals("lawYear")
			  || fields[i].equals("getPaperYear")
			  || fields[i].equals("paperYear") || fields[i].equals("years")
			){
				return " order by obj."+fields[i]+" desc";
			}
		}
		return null;
	}

	public boolean execHql(String sql) {
		return dao.execHql(sql);
	}
}
